/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * NodoCommandPanel.java
 *
 * Created on 21-mrt-2010, 19:10:28
 */

package nl.lemval.nododue.tabs;


import java.awt.GridLayout;
import java.io.File;
import java.util.Collection;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import nl.lemval.nododue.NodoDueManager;
import nl.lemval.nododue.NodoDueManagerView;
import nl.lemval.nododue.cmd.CommandInfo;
import nl.lemval.nododue.cmd.CommandLoader;
import nl.lemval.nododue.cmd.CommandType;
import nl.lemval.nododue.cmd.NodoCommand;
import nl.lemval.nododue.component.EventActionPanel;
import nl.lemval.nododue.component.MacroListModel;
import nl.lemval.nododue.util.NodoMacro;
import nl.lemval.nododue.util.NodoMacroHandler;
import nl.lemval.nododue.util.NodoMacroList;
import org.jdesktop.application.Action;
import org.jdesktop.application.Task;

/**
 *
 * @author Michael
 */
public class MacroPanel extends NodoBasePanel {

    private EventActionPanel eventPanel;
    private EventActionPanel commandPanel;
    private MacroListModel macroListModel;
    
    /** Creates new form NodoCommandPanel */
    public MacroPanel(NodoDueManagerView view) {
        super(view);

        eventPanel = new EventActionPanel(view, getResourceString("macro_event"));
        commandPanel = new EventActionPanel(view, getResourceString("macro_action"));
        macroListModel = new MacroListModel();

        eventPanel.setAutoUnit(true);
        commandPanel.setAutoUnit(true);

        Collection<CommandInfo> cmds = CommandLoader.getActions(
		CommandType.MACRO.add(CommandType.COMMAND).add(CommandType.EVENT) );
        eventPanel.addAll(cmds);

        cmds = CommandLoader.getActions(CommandType.COMMAND.add(CommandType.SETTING));
        // CommandLoader.removeActions(cmds, CommandType.SERIALONLY);
        commandPanel.addAll(cmds);

        initComponents();
	updateCount();

        panel1.setLayout(new GridLayout());
        panel2.setLayout(new GridLayout());
        panel1.add(eventPanel);
        panel2.add(commandPanel);

        macrolist.addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent e) {
                if (e.getValueIsAdjusting() == false) {
                    Object[] selected = macrolist.getSelectedValues();
                    if ( selected.length == 1 ) {
                        NodoMacro nm = (NodoMacro) selected[0];
                        if ( nm != null ) {
                            eventPanel.setSelected(nm.getEvent());
                            commandPanel.setSelected(nm.getAction());
                        }
                    }
                }
            }
        });
    }

    @Override
    public void setVisible(boolean aFlag) {
        if ( aFlag == true ) {
            eventPanel.updateAppliances();
        }
        super.setVisible(aFlag);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        panel1 = new javax.swing.JPanel();
        panel2 = new javax.swing.JPanel();
        panel3 = new javax.swing.JPanel();
        nameLabel = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        macrolist = new javax.swing.JList();
        availableLabel = new javax.swing.JLabel();
        jPanel1 = new javax.swing.JPanel();
        retrieve = new javax.swing.JButton();
        store = new javax.swing.JButton();
        add = new javax.swing.JButton();
        remove = new javax.swing.JButton();
        moveUp = new javax.swing.JLabel();
        moveDown = new javax.swing.JLabel();

        setName("Form"); // NOI18N

        panel1.setName("panel1"); // NOI18N

        org.jdesktop.layout.GroupLayout panel1Layout = new org.jdesktop.layout.GroupLayout(panel1);
        panel1.setLayout(panel1Layout);
        panel1Layout.setHorizontalGroup(
            panel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 196, Short.MAX_VALUE)
        );
        panel1Layout.setVerticalGroup(
            panel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 337, Short.MAX_VALUE)
        );

        panel2.setName("panel2"); // NOI18N

        org.jdesktop.layout.GroupLayout panel2Layout = new org.jdesktop.layout.GroupLayout(panel2);
        panel2.setLayout(panel2Layout);
        panel2Layout.setHorizontalGroup(
            panel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 196, Short.MAX_VALUE)
        );
        panel2Layout.setVerticalGroup(
            panel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 337, Short.MAX_VALUE)
        );

        panel3.setName("panel3"); // NOI18N

        nameLabel.setFont(nameLabel.getFont().deriveFont(nameLabel.getFont().getStyle() | java.awt.Font.BOLD, nameLabel.getFont().getSize()+1));
        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(nl.lemval.nododue.NodoDueManager.class).getContext().getResourceMap(MacroPanel.class);
        nameLabel.setText(resourceMap.getString("nameLabel.text")); // NOI18N
        nameLabel.setName("nameLabel"); // NOI18N

        jScrollPane1.setName("jScrollPane1"); // NOI18N

        macrolist.setModel(macroListModel);
        macrolist.setName("macrolist"); // NOI18N
        jScrollPane1.setViewportView(macrolist);

        availableLabel.setText(resourceMap.getString("availableLabel.text")); // NOI18N
        availableLabel.setToolTipText(resourceMap.getString("availableLabel.toolTipText")); // NOI18N
        availableLabel.setName("availableLabel"); // NOI18N

        org.jdesktop.layout.GroupLayout panel3Layout = new org.jdesktop.layout.GroupLayout(panel3);
        panel3.setLayout(panel3Layout);
        panel3Layout.setHorizontalGroup(
            panel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(panel3Layout.createSequentialGroup()
                .addContainerGap()
                .add(panel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 265, Short.MAX_VALUE)
                    .add(panel3Layout.createSequentialGroup()
                        .add(nameLabel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 131, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 87, Short.MAX_VALUE)
                        .add(availableLabel)))
                .addContainerGap())
        );
        panel3Layout.setVerticalGroup(
            panel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(panel3Layout.createSequentialGroup()
                .addContainerGap()
                .add(panel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(nameLabel)
                    .add(availableLabel))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE))
        );

        jPanel1.setName("jPanel1"); // NOI18N

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(nl.lemval.nododue.NodoDueManager.class).getContext().getActionMap(MacroPanel.class, this);
        retrieve.setAction(actionMap.get("retrieveMacros")); // NOI18N
        retrieve.setText(resourceMap.getString("retrieve.text")); // NOI18N
        retrieve.setName("retrieve"); // NOI18N

        store.setAction(actionMap.get("storeMacros")); // NOI18N
        store.setText(resourceMap.getString("store.text")); // NOI18N
        store.setName("store"); // NOI18N

        add.setAction(actionMap.get("addMacro")); // NOI18N
        add.setText(resourceMap.getString("add.text")); // NOI18N
        add.setName("add"); // NOI18N

        org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .add(retrieve)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(store)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 125, Short.MAX_VALUE)
                .add(add))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(retrieve)
                    .add(store)
                    .add(add))
                .addContainerGap())
        );

        remove.setAction(actionMap.get("removeMacro")); // NOI18N
        remove.setText(resourceMap.getString("remove.text")); // NOI18N
        remove.setName("remove"); // NOI18N

        moveUp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/nl/lemval/nododue/resources/images_icon_up.png"))); // NOI18N
        moveUp.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        moveUp.setName("moveUp"); // NOI18N
        moveUp.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                moveUp(evt);
            }
        });

        moveDown.setIcon(new javax.swing.ImageIcon(getClass().getResource("/nl/lemval/nododue/resources/images_icon_dwn.png"))); // NOI18N
        moveDown.setText(resourceMap.getString("moveDown.text")); // NOI18N
        moveDown.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        moveDown.setName("moveDown"); // NOI18N
        moveDown.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                moveDown(evt);
            }
        });

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, layout.createSequentialGroup()
                        .add(panel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(panel2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(layout.createSequentialGroup()
                        .add(10, 10, 10)
                        .add(remove)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 117, Short.MAX_VALUE)
                        .add(moveDown)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(moveUp)
                        .addContainerGap())
                    .add(panel3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
        );

        layout.linkSize(new java.awt.Component[] {panel1, panel2}, org.jdesktop.layout.GroupLayout.HORIZONTAL);

        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, panel2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, panel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, panel3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(layout.createSequentialGroup()
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(moveUp)
                            .add(remove)
                            .add(moveDown))
                        .addContainerGap())))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void moveDown(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_moveDown
        doMove(false);
    }//GEN-LAST:event_moveDown

    private void moveUp(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_moveUp
        doMove(true);
    }//GEN-LAST:event_moveUp

    @Action
    public Task retrieveMacros() {
        if ( NodoDueManager.hasConnection() )
            return new RetrieveMacrosTask(org.jdesktop.application.Application.getInstance(nl.lemval.nododue.NodoDueManager.class));
        return null;
    }

    public void loadFromFile(File selected) {
        NodoMacroList list = new NodoMacroList();
        if ( list.load(selected) ) {
            macroListModel.setContent(list);
	    updateCount();
	}
    }

    private void updateCount() {
	int size = macroListModel.getSize();
	int avail = NodoMacroList.MAXLENGTH - size;
	availableLabel.setText( size + "/" + NodoMacroList.MAXLENGTH);
	switch (avail) {
	    case NodoMacroList.MAXLENGTH:
		availableLabel.setToolTipText(NodoDueManager.getMessage("MacroPanel.AllAvailable"));
		break;
	    case 1:
		availableLabel.setToolTipText(NodoDueManager.getMessage("MacroPanel.OneAvailable"));
		break;
	    case 0:
		availableLabel.setToolTipText(NodoDueManager.getMessage("MacroPanel.NoneAvailable"));
		break;
	    default:
		availableLabel.setToolTipText(NodoDueManager.getMessage("MacroPanel.SetAvailable", avail));
		break;
	}
    }

    public void saveToFile(File selected, boolean overwrite) {
        NodoMacroList list = macroListModel.getList();
        list.save(selected, overwrite);
    }

    private class RetrieveMacrosTask extends org.jdesktop.application.Task<Object, Void> {
        RetrieveMacrosTask(org.jdesktop.application.Application app) {
            // Runs on the EDT.  Copy GUI state that
            // doInBackground() depends on from parameters
            // to RetrieveMacrosTask fields, here.
            super(app);
        }
        @Override protected Object doInBackground() {
            // Your Task's code here.  This method runs
            // on a background thread, so don't reference
            // the Swing GUI from here.
            return new NodoMacroHandler().getList();
        }
        @Override protected void succeeded(Object result) {
            // Runs on the EDT.  Update the GUI based on
            // the result computed by doInBackground().
            NodoMacroList list = (NodoMacroList) result;
            macroListModel.setContent(list);
	    updateCount();
        }
    }

    @Action
    public Task storeMacros() {
        if ( NodoDueManager.hasConnection() )
            return new StoreMacrosTask(org.jdesktop.application.Application.getInstance(nl.lemval.nododue.NodoDueManager.class));
        return null;
    }

    private class StoreMacrosTask extends org.jdesktop.application.Task<Object, Void> {
        StoreMacrosTask(org.jdesktop.application.Application app) {
            // Runs on the EDT.  Copy GUI state that
            // doInBackground() depends on from parameters
            // to RetrieveMacrosTask fields, here.
            super(app);
        }
        @Override protected Object doInBackground() {
            // Your Task's code here.  This method runs
            // on a background thread, so don't reference
            // the Swing GUI from here.
            return new NodoMacroHandler().writeList(macroListModel.getList());
        }
        @Override protected void succeeded(Object result) {
            // Runs on the EDT.  Update the GUI based on
            // the result computed by doInBackground().
        }
    }

    @Action
    public void removeMacro() {
        Object[] selected = macrolist.getSelectedValues();
        for (int i = 0; i < selected.length; i++) {
            macroListModel.remove(selected[i]);
	    updateCount();
        }
    }

    @Action
    public void addMacro() {
        NodoCommand event = eventPanel.getSelectedItem();
        NodoCommand action = commandPanel.getSelectedItem();
        if ( event != null && action != null ) {
            macroListModel.add(new NodoMacro(event, action));
	    updateCount();
        }
    }

    private void doMove(boolean up) {
        int numSel = macrolist.getSelectedValues().length;
        if ( numSel != 1 ) {
            return;
        }
        int idx = macrolist.getSelectedIndex();
        if ( idx != -1 )
            macroListModel.move(idx, up);
        macrolist.setSelectedIndex(up ? idx-1 : idx+1);
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton add;
    private javax.swing.JLabel availableLabel;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JList macrolist;
    private javax.swing.JLabel moveDown;
    private javax.swing.JLabel moveUp;
    private javax.swing.JLabel nameLabel;
    private javax.swing.JPanel panel1;
    private javax.swing.JPanel panel2;
    private javax.swing.JPanel panel3;
    private javax.swing.JButton remove;
    private javax.swing.JButton retrieve;
    private javax.swing.JButton store;
    // End of variables declaration//GEN-END:variables

}
